// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network;

import java.nio.ByteBuffer;
import org.joml.Vector3f;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.core.Core;
import zombie.core.SpriteRenderer;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.iso.IsoChunk;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoUtils;
import zombie.iso.IsoWorld;
import zombie.vehicles.BaseVehicle;

public final class PassengerMap {
    private static final int CHUNKS = 7;
    private static final int MAX_PASSENGERS = 16;
    private static final PassengerMap.PassengerLocal[] perPlayerPngr = new PassengerMap.PassengerLocal[4];
    private static final PassengerMap.DriverLocal[] perPlayerDriver = new PassengerMap.DriverLocal[4];

    public static void updatePassenger(IsoPlayer player) {
        if (player != null && player.getVehicle() != null && !player.getVehicle().isDriver(player)) {
            IsoGameCharacter isoGameCharacter = player.getVehicle().getDriver();
            if (isoGameCharacter instanceof IsoPlayer && !((IsoPlayer)isoGameCharacter).isLocalPlayer()) {
                PassengerMap.PassengerLocal passengerLocal = perPlayerPngr[player.PlayerIndex];
                passengerLocal.chunkMap = IsoWorld.instance.CurrentCell.ChunkMap[player.PlayerIndex];
                passengerLocal.updateLoaded();
            }
        }
    }

    public static void serverReceivePacket(ByteBuffer bb, UdpConnection connection) {
        byte _byte = bb.get();
        int int0 = bb.getInt();
        int int1 = bb.getInt();
        long _long = bb.getLong();
        IsoPlayer isoPlayer = connection.players[_byte];
        if (isoPlayer != null && isoPlayer.getVehicle() != null) {
            IsoGameCharacter isoGameCharacter = isoPlayer.getVehicle().getDriver();
            if (isoGameCharacter instanceof IsoPlayer && isoGameCharacter != isoPlayer) {
                UdpConnection udpConnection = GameServer.getConnectionFromPlayer((IsoPlayer)isoGameCharacter);
                if (udpConnection != null) {
                    ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
                    PacketTypes.PacketType.PassengerMap.doPacket(byteBufferWriter);
                    byteBufferWriter.putShort(isoPlayer.getVehicle().VehicleID);
                    byteBufferWriter.putByte((byte)isoPlayer.getVehicle().getSeat(isoPlayer));
                    byteBufferWriter.putInt(int0);
                    byteBufferWriter.putInt(int1);
                    byteBufferWriter.putLong(_long);
                    PacketTypes.PacketType.PassengerMap.send(udpConnection);
                }
            }
        }
    }

    public static void clientReceivePacket(ByteBuffer bb) {
        short _short = bb.getShort();
        byte _byte = bb.get();
        int int0 = bb.getInt();
        int int1 = bb.getInt();
        long _long = bb.getLong();

        for (int int2 = 0; int2 < IsoPlayer.numPlayers; int2++) {
            IsoPlayer isoPlayer = IsoPlayer.players[int2];
            if (isoPlayer != null && isoPlayer.getVehicle() != null) {
                BaseVehicle baseVehicle = isoPlayer.getVehicle();
                if (baseVehicle.VehicleID == _short && baseVehicle.isDriver(isoPlayer)) {
                    PassengerMap.DriverLocal driverLocal = perPlayerDriver[int2];
                    PassengerMap.PassengerRemote passengerRemote = driverLocal.passengers[_byte];
                    if (passengerRemote == null) {
                        passengerRemote = driverLocal.passengers[_byte] = new PassengerMap.PassengerRemote();
                    }

                    passengerRemote.setLoaded(int0, int1, _long);
                }
            }
        }
    }

    public static boolean isChunkLoaded(BaseVehicle vehicle, int wx, int wy) {
        if (!GameClient.bClient) {
            return false;
        } else if (vehicle != null && wx >= 0 && wy >= 0) {
            IsoGameCharacter isoGameCharacter0 = vehicle.getDriver();
            if (isoGameCharacter0 instanceof IsoPlayer && ((IsoPlayer)isoGameCharacter0).isLocalPlayer()) {
                int int0 = ((IsoPlayer)isoGameCharacter0).PlayerIndex;
                PassengerMap.DriverLocal driverLocal = perPlayerDriver[int0];

                for (int int1 = 1; int1 < vehicle.getMaxPassengers(); int1++) {
                    PassengerMap.PassengerRemote passengerRemote = driverLocal.passengers[int1];
                    if (passengerRemote != null && passengerRemote.wx != -1) {
                        IsoGameCharacter isoGameCharacter1 = vehicle.getCharacter(int1);
                        if (isoGameCharacter1 instanceof IsoPlayer && !((IsoPlayer)isoGameCharacter1).isLocalPlayer()) {
                            int int2 = passengerRemote.wx - 3;
                            int int3 = passengerRemote.wy - 3;
                            if (wx >= int2
                                && wy >= int3
                                && wx < int2 + 7
                                && wy < int3 + 7
                                && (passengerRemote.loaded & 1L << wx - int2 + (wy - int3) * 7) == 0L) {
                                return false;
                            }
                        } else {
                            passengerRemote.wx = -1;
                        }
                    }
                }

                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static void render(int playerIndex) {
        if (GameClient.bClient) {
            IsoPlayer isoPlayer = IsoPlayer.players[playerIndex];
            if (isoPlayer != null && isoPlayer.getVehicle() != null) {
                BaseVehicle baseVehicle = isoPlayer.getVehicle();
                int int0 = Core.TileScale;
                byte _byte = 10;
                float float0 = 0.1F;
                float float1 = 0.1F;
                float float2 = 0.1F;
                float float3 = 0.75F;
                float float4 = 0.0F;
                PassengerMap.DriverLocal driverLocal = perPlayerDriver[playerIndex];

                for (int int1 = 1; int1 < baseVehicle.getMaxPassengers(); int1++) {
                    PassengerMap.PassengerRemote passengerRemote = driverLocal.passengers[int1];
                    if (passengerRemote != null && passengerRemote.wx != -1) {
                        IsoGameCharacter isoGameCharacter = baseVehicle.getCharacter(int1);
                        if (isoGameCharacter instanceof IsoPlayer && !((IsoPlayer)isoGameCharacter).isLocalPlayer()) {
                            for (int int2 = 0; int2 < 7; int2++) {
                                for (int int3 = 0; int3 < 7; int3++) {
                                    boolean _boolean = (passengerRemote.loaded & 1L << int3 + int2 * 7) != 0L;
                                    if (!_boolean) {
                                        float float5 = (float)((passengerRemote.wx - 3 + int3) * _byte);
                                        float float6 = (float)((passengerRemote.wy - 3 + int2) * _byte);
                                        float float7 = IsoUtils.XToScreenExact(float5, float6 + (float)_byte, float4, 0);
                                        float float8 = IsoUtils.YToScreenExact(float5, float6 + (float)_byte, float4, 0);
                                        SpriteRenderer.instance
                                            .renderPoly(
                                                (float)((int)float7),
                                                (float)((int)float8),
                                                (float)((int)(float7 + (float)(_byte * 64 / 2 * int0))),
                                                (float)((int)(float8 - (float)(_byte * 32 / 2 * int0))),
                                                (float)((int)(float7 + (float)(_byte * 64 * int0))),
                                                (float)((int)float8),
                                                (float)((int)(float7 + (float)(_byte * 64 / 2 * int0))),
                                                (float)((int)(float8 + (float)(_byte * 32 / 2 * int0))),
                                                float0,
                                                float1,
                                                float2,
                                                float3
                                            );
                                    }
                                }
                            }
                        } else {
                            passengerRemote.wx = -1;
                        }
                    }
                }
            }
        }
    }

    public static void Reset() {
        for (int int0 = 0; int0 < 4; int0++) {
            PassengerMap.PassengerLocal passengerLocal = perPlayerPngr[int0];
            passengerLocal.wx = -1;
            PassengerMap.DriverLocal driverLocal = perPlayerDriver[int0];

            for (int int1 = 0; int1 < 16; int1++) {
                PassengerMap.PassengerRemote passengerRemote = driverLocal.passengers[int1];
                if (passengerRemote != null) {
                    passengerRemote.wx = -1;
                }
            }
        }
    }

    static {
        for (int _int = 0; _int < 4; _int++) {
            perPlayerPngr[_int] = new PassengerMap.PassengerLocal(_int);
            perPlayerDriver[_int] = new PassengerMap.DriverLocal();
        }
    }

    private static final class DriverLocal {
        final PassengerMap.PassengerRemote[] passengers = new PassengerMap.PassengerRemote[16];
    }

    private static final class PassengerLocal {
        final int playerIndex;
        IsoChunkMap chunkMap;
        int wx = -1;
        int wy = -1;
        long loaded = 0L;

        PassengerLocal(int _int) {
            this.playerIndex = _int;
        }

        boolean setLoaded() {
            int int0 = this.chunkMap.WorldX;
            int int1 = this.chunkMap.WorldY;
            Vector3f vector3f = IsoPlayer.players[this.playerIndex].getVehicle().jniLinearVelocity;
            float float0 = Math.abs(vector3f.x);
            float float1 = Math.abs(vector3f.z);
            boolean boolean0 = vector3f.x < 0.0F && float0 > float1;
            boolean boolean1 = vector3f.x > 0.0F && float0 > float1;
            boolean boolean2 = vector3f.z < 0.0F && float1 > float0;
            boolean boolean3 = vector3f.z > 0.0F && float1 > float0;
            if (boolean1) {
                int0++;
            } else if (boolean0) {
                int0--;
            } else if (boolean2) {
                int1--;
            } else if (boolean3) {
                int1++;
            }

            long _long = 0L;

            for (int int2 = 0; int2 < 7; int2++) {
                for (int int3 = 0; int3 < 7; int3++) {
                    IsoChunk isoChunk = this.chunkMap.getChunk(IsoChunkMap.ChunkGridWidth / 2 - 3 + int3, IsoChunkMap.ChunkGridWidth / 2 - 3 + int2);
                    if (isoChunk != null && isoChunk.bLoaded) {
                        _long |= 1L << int3 + int2 * 7;
                    }
                }
            }

            boolean boolean4 = int0 != this.wx || int1 != this.wy || _long != this.loaded;
            if (boolean4) {
                this.wx = int0;
                this.wy = int1;
                this.loaded = _long;
            }

            return boolean4;
        }

        void updateLoaded() {
            if (this.setLoaded()) {
                this.clientSendPacket(GameClient.connection);
            }
        }

        void clientSendPacket(UdpConnection udpConnection) {
            ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
            PacketTypes.PacketType.PassengerMap.doPacket(byteBufferWriter);
            byteBufferWriter.putByte((byte)this.playerIndex);
            byteBufferWriter.putInt(this.wx);
            byteBufferWriter.putInt(this.wy);
            byteBufferWriter.putLong(this.loaded);
            PacketTypes.PacketType.PassengerMap.send(udpConnection);
        }
    }

    private static final class PassengerRemote {
        int wx = -1;
        int wy = -1;
        long loaded = 0L;

        void setLoaded(int int0, int int1, long _long) {
            this.wx = int0;
            this.wy = int1;
            this.loaded = _long;
        }
    }
}
